package com.ec50n9.server.module.file

import com.ec50n9.server.common.ApiException
import com.ec50n9.server.module.common.AppCode
import org.springframework.web.bind.annotation.*
import org.springframework.web.multipart.MultipartFile
import org.springframework.web.multipart.MultipartHttpServletRequest
import java.io.File
import java.io.FileInputStream
import java.io.FileNotFoundException
import java.util.*
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse

@RestController
@RequestMapping("/api/files")
class FileController {

    val baseUrlPath = "/api/files/download/"
    val filePath = "/Users/ec50n9/Downloads/upload/"

    fun saveFile(file: MultipartFile, excludeSuffix: Array<String> = arrayOf()): String {
        var fileName = file.originalFilename ?: throw ApiException(AppCode.OBJECT_NOT_FOUND, "无法获取文件名")
        val suffixName = fileName.substring(fileName.lastIndexOf(".") + 1)
        if (suffixName in excludeSuffix) {
            throw ApiException(AppCode.OBJECT_NOT_SUPPORTED, "不支持的后缀名: $suffixName")
        }
        fileName = UUID.randomUUID().toString() + fileName
        val fileFullPath = filePath + fileName
        val dest = File(fileFullPath)
        if (!dest.parentFile.exists()) {
            dest.parentFile.mkdirs()
        }
        file.transferTo(dest)
        return fileName
    }

    /**
     * 单文件上传
     */
    @PostMapping("/upload")
    fun upload(@RequestParam file: MultipartFile): String {
        return baseUrlPath + saveFile(file, arrayOf("mp4"))
    }

    @PostMapping("/uploads")
    fun uploads(request: HttpServletRequest): List<String> {
        request as MultipartHttpServletRequest
        val files = request.getFiles("file")
        if (files.size > 10) {
            throw ApiException(AppCode.OUT_OF_RANGE, "最多只能上传10个文件")
        }
        val pathList = mutableListOf<String>()
        files.forEach {
            pathList.add(baseUrlPath + saveFile(it))
        }
        return pathList
    }

    @GetMapping("/download/{fileName}")
    fun download(@PathVariable fileName: String, response: HttpServletResponse) {
        val file = File("$filePath$fileName")
        response.contentType = "application/force-download"
        response.setHeader("Content-Disposition", "attachment;fileName=$fileName")
        var fis: FileInputStream? = null
        try {
            fis = file.inputStream()
        } catch (e: FileNotFoundException) {
            throw ApiException(AppCode.OBJECT_NOT_FOUND, "文件不存在！")
        }
        with(fis) {
            val buf = ByteArray(1024)
            var len: Int
            while (read(buf).also { len = it } != -1) {
                response.outputStream.write(buf, 0, len)
            }
            close()
        }
    }
}